Fix static shell build failing on Ubuntu 24.04 with a missing firmware ELF#139
Fix static shell build failing on Ubuntu 24.04 with a missing firmware ELF#139merkelmarrow wants to merge 1 commit into
Conversation
…u 24.04 _environment_with_udev_preload forces LD_PRELOAD=libudev.so.1 onto the whole Vivado process tree as a container workaround. That preload is inherited by the bundled MicroBlaze cross-compiler that builds the DDRMC calibration firmware, which runs under its own OE-SDK loader with a restricted library path. On Ubuntu 24.04 the host libudev.so.1 is linked aginst libcap.so.2, which is absent from that path, so the cross-compiler aborts with "libcap.so.2: cannot open shared object file" and exits 127. The firmware never compiles, phy_ddrmc.elf is never produced, and synthesis fails later with a "File does not exist" for the missing ELF. The child stderr is lost, so the failure is silent. Ubuntu 22.04 is not affected because its libudev has no libcap dependency. Preload libudev together with its runtime dependency libcap.so.2 so the forced preload resolves inside the cross-compiler's restricted library path. Adding libcap is harmless where it is not needed. Relates to Xilinx#117. Signed-off-by: Marco Blackwell <mblackwe@amd.com>
|
I'm just thinking out loud here — if this is indeed the problem, since this preload/env variable hacking is mostly a workaround for "a weird issue when running Vivado in a container", maybe we should only apply it when running inside a container? We could probably move this logic into run-with-docker so it doesn't potentially mess with builds outside the container. |
|
@taraxacum45e9a that's a fair point long-term. As it stands, the logic only preloads libudev for Vivado processes, and if you were to move it into the docker runtime you'd have to export it container-wide which would arguably interfere more rather than less. Otherwise you'd need some logic to detect if you are in a container, and you'd still need the logic to float libcap on 24.04, so it's probably out of scope for this fix. |
Building the static shell from source fails on Ubuntu 24.04. Synthesis runs for a while and then stops with a confusing error saying a
.elffile "does not exist". The same build works on Ubuntu 22.04, which made the failure look like an unsupported OS rather than a real bug. This change makes the build work on 24.04.It matches the behaviour reported in #117.
Problem
To work around an issue running Vivado inside containers, SLASH preloads a system library (
libudev) into Vivado. That preload is inherited by every process Vivado starts, including the compiler it uses to build the memory controller's calibration firmware. That firmware is what becomes the missing.elf.On Ubuntu 24.04 that system library started depending on a second library (
libcap) that the bundled firmware compiler cannot see. So the compiler fails to start, the firmware is never built, and the error stays hidden until much later, when synthesis looks for the file that was never produced. On Ubuntu 22.04 the library had no such dependency, which is exactly why 22.04 was unaffected.Investigation
I was able to narrow down the issue with several rounds of A/B tests with a small reproducer of the failing step. The first clue was that the failure could not be reproduced in isolation. Building the design directly with Vivado on the same 24.04 host always succeeded. The only thing that ever failed was the build driven through SLASH's installer, which meant the difference had to be in the environment the installer sets up.
Comparing the installer's Vivado invocation against a direct one, the only meaningful difference was the inherited
libudevpreload.The third line is the fix.
Changes
When SLASH applies the preload, it now also brings along the dependency the preloaded library needs, so the firmware compiles successfully on 24.04.
Testing